﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinalPointSet.Model.Asset;
using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Model.MockData;
using FinalPointSet.Model.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static FinalPointSet.Model.Manager.MessageManager;

namespace FinalPointSet.ViewModel.Page.MockData
{
    public partial class GeneratePageViewModel : ObservableObject
    {
        /// <summary>
        /// 最大生成的大小
        /// </summary>
        private const int MaxGenerateCount = 500000;
        /// <summary>
        /// 模拟数据节点集合
        /// </summary>
        [ObservableProperty]
        private List<List<string>> _FieldDatas = [];
        public List<string> Header { get; set; } = [];

        /// <summary>
        /// 生成的数量
        /// </summary>
        [ObservableProperty]
        private int _GenerateCount = 100;
        /// <summary>
        /// 是否生成表头
        /// </summary>
        [ObservableProperty]
        private bool _HasHeader = true;
        /// <summary>
        /// 导出文件的所有类型
        /// </summary>
        [ObservableProperty]
        private List<ExportFileType> _ExportTypes = Enum.GetValues(typeof(ExportFileType)).Cast<ExportFileType>().ToList();
        /// <summary>
        /// 导出文件的类型
        /// </summary>
        [ObservableProperty]
        private ExportFileType _ExportType = ExportFileType.SQL;
        /// <summary>
        /// 导出文件的路径
        /// </summary>
        [ObservableProperty]
        private string _ExportPath = AssetUtil.GetAbsolutePath(Path.MockDataExport);
        /// <summary>
        /// 导出文件的路径
        /// </summary>
        [ObservableProperty]
        private string _ExportFilePath = string.Empty;
        public List<MockField> MockFields { get; set; } = [];

        /// <summary>
        /// 导出的进度文本
        /// </summary>
        [ObservableProperty]
        private string _ProgressText = "0%";
        /// <summary>
        /// 导出的进度
        /// </summary>
        [ObservableProperty]
        private int _Progress = 0;
        /// <summary>
        /// 是否能够操作
        /// </summary>
        [ObservableProperty]
        private bool _IsUserCanOperate = true;
        /// <summary>
        /// 是否能够暂停导出
        /// </summary>
        [ObservableProperty]
        private bool _IsUserCanCancel = false;
        /// <summary>
        /// 表名
        /// </summary>
        [ObservableProperty]
        private string _TableName = "";
        /// <summary>
        /// 取消导出令牌
        /// </summary>
        private CancellationTokenSource cts = new();
        public GeneratePageViewModel() { }
        /// <summary>
        /// 打开文件资源管理器对话框, 选择路径
        /// </summary>
        [RelayCommand]
        private void SelectFloderBrowser()
        {
            FolderBrowserDialog folderBrowserDialog = new()
            {
                Description = "请选择导出文件的保存路径",
                SelectedPath = AssetUtil.GetAbsolutePath(Path.MockDataExport)
            };
            var result = folderBrowserDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                ExportPath = folderBrowserDialog.SelectedPath;
            };
            folderBrowserDialog.Dispose();

        }
        /// <summary>
        /// 导出文件
        /// </summary>
        [RelayCommand]
        private async Task Export()
        {
            Debug.Print($"MockDataGenerateViewModel.Export()");
            if (MockFields == null || MockFields.Count == 0) return;
            if (GenerateCount > MaxGenerateCount)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"超过单次生成最大数据数量{MaxGenerateCount}条"));
                return;
            }
            else if (GenerateCount <= 0)
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"生成的数据量必须大于0"));
                return;
            }
            else if (string.IsNullOrEmpty(TableName))
            {
                Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Error, $"导出的表名不能为空"));
                return;
            }
            //静止用户操作
            IsUserCanOperate = false;
            IsUserCanCancel = true;
            //获取字典的数据
            List<MockRule> customScripts = AssetManager.Instance.GetJsonObjectList<MockRule>();
            var progressIndicator = new Progress<int>(progress =>
            {
                // 更新ProgressBar的值，注意这里需要在UI线程上执行  
                Progress = progress;
                ProgressText = $"{progress}%";
            });
            //解析
            cts = new();
            try
            {
                MockResult? mockResult = await MockParser.Parse(MockFields, customScripts, GenerateCount, progressIndicator, cts.Token);
                if (mockResult != null)
                {
                    if (ExportType == ExportFileType.CSV || ExportType == ExportFileType.TXT)
                    {
                        MockFormatter.ExportFile(mockResult, ExportPath, ExportType, HasHeader);

                    }
                    else if (ExportType == ExportFileType.SQL)
                    {
                        MockFormatter.ExportSQL(mockResult, ExportPath, TableName);
                    }
                    Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, "导出数据成功, 请前往目标文件夹查看!"));
                    MethodUtil.OpenFileLocationInExplorer(ExportPath);
                }

            }
            catch (OperationCanceledException)
            {
                // 处理取消情况，例如更新UI以反映操作已取消
            }
            finally
            {
                cts.Dispose();
                //恢复用户操作
                IsUserCanOperate = true;
                IsUserCanCancel = false;
            }
        }

        /// <summary>
        /// 取消导出
        /// </summary>
        [RelayCommand]
        private void CancelExport()
        {
            Debug.Print("MockDataGenerateViewModel.CancelExport()");
            cts.Cancel();
            IsUserCanCancel = false;
            IsUserCanOperate = true;
            Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.MainView, GrowlMsgType.Success, "取消导出数据成功!"));
        }
    }
}
